package edu.usx.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import edu.usx.server.config.MailService;
import edu.usx.server.config.security.JwtTokenUtil;
import edu.usx.server.pojo.User;
import edu.usx.server.mapper.UserMapper;
import edu.usx.server.pojo.RespBean;
import edu.usx.server.pojo.dto.*;
import edu.usx.server.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author RawMieEgg
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private MailService mailService;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    /**
     * 用户登录
     * @param username
     * @param password
     * @param request
     * @return
     */
    @Override
    public RespBean login (String username, String password, String code, HttpServletRequest request) {
        String captcha=(String) request.getSession().getAttribute("captcha");
        if(StringUtils.isEmpty(code)||!captcha.equalsIgnoreCase(code)){
            return RespBean.error("验证码错误，请重新输入！");
        }
        UserDetails userDetails=userDetailsService.loadUserByUsername(username);
        //账号判断
        if(userDetails==null||!passwordEncoder.matches(password,userDetails.getPassword())){
            return RespBean.error("用户名或密码不正确");
        }
        if(!userDetails.isEnabled()){
            return RespBean.error("账号被禁用！");
        }
        //更新security登录用户对象
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(userDetails,
                null,userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //生成token
        String token=jwtTokenUtil.generateToken(userDetails);
        Map<String,String> tokenMap=new HashMap<>();
        tokenMap.put("token",token);
        tokenMap.put("tokenHead",tokenHead);
        return RespBean.success("登录成功！",tokenMap);
    }

    /**
     * 根据用户名获取完整用户对象
     * @param username
     * @return
     */
    @Override
    public User getUserByUserName(String username) {
        return userMapper.selectOne(new QueryWrapper<User>().eq("username",username)
                );
    }

    /**
     * 根据用户id来修改用户信息
     *
     * @param userDto
     * @return
     */
    @Override
    public RespBean updateById(UserDto userDto) {

        User user = new User();
        BeanUtils.copyProperties(userDto, user);
        //获取用户id
        int userId = ((User)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
        //查看当前用户是否可用
        boolean enabled = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).isEnabled();
        if (!enabled){
            return RespBean.error("当前用户不可用");
        }
        //1.设置用户id
        user.setId(userId);
        user.setEnabled(enabled);
        //2.设置更新时间
        user.setUpdate_time(LocalDateTime.now());
        boolean update = updateById(user);
        if (!update){
            return RespBean.error("用户信息修改失败");
        }
        return RespBean.success("用户信息修改成功");
    }

    /**
     * 用户注册
     *
     * @param user
     * @return
     */

    public RespBean register (UserregisterDto user, HttpServletRequest request) {
//        String email=user.getEmail();
//        mailService.sendEmailCode(email,request);

        HttpSession session = request.getSession();
        String verifySession = (String) session.getAttribute("verify");
        String email =user.getEmail();
        String emailSession =(String) session.getAttribute("email");
        String verify = user.getVerify();
        if (verifySession==null){
            return RespBean.error("请发送邮箱验证码");
        }
        if(StringUtils.isEmpty(email)||!email.equalsIgnoreCase(emailSession)){
            System.out.println(email+"**"+emailSession);
            return RespBean.error("输入邮箱为空，或获取验证码邮箱与当前填写邮箱不一致");
        }
        String captcha=(String) request.getSession().getAttribute("verify");
        if(StringUtils.isEmpty(verify)||!verify.equalsIgnoreCase(verifySession)){
            return RespBean.error("验证码错误，请重新输入！");
        }
        UserregisterDto Jusername=userMapper.selectusername(user);
        if(Jusername!=null){
            return RespBean.error("用户名已存在，请重新输入！");
        }
        //TODO 后续判断

        user.setCreate_time(LocalDateTime.now());
        user.setUpdate_time(LocalDateTime.now());
        String password = passwordEncoder.encode(user.getPassword());
        user.setPassword(password);
        userMapper.register(user);
        return RespBean.success("成功注册");



    }




        /**
         * 根据用户邮箱获取完整用户对象
         * @param email
         * @return
         */
    @Override
    public User getUserByUserEmail(String email) {
        return userMapper.selectOne(new QueryWrapper<User>().eq("email",email)
        );
    }

    /**
     * 邮箱验证码验证重置密码
     * @param userResetPwdDto 用户重置密码对象
     * @return
     */
    public RespBean resetPasswordByEmail(UserResetPwdDto userResetPwdDto, HttpServletRequest request) {
        //检查session是否存验证码
        HttpSession session = request.getSession();
        if(session.getAttribute("verify")==null){
            return RespBean.error("请先发送验证码！");
        }
        String verify=(String)session.getAttribute("verify");
        String code=userResetPwdDto.getVerify();
        String email=userResetPwdDto.getEmail();
        String password=userResetPwdDto.getPassword();
        if(StringUtils.isEmpty(code)||!verify.equalsIgnoreCase(code)){
            return RespBean.error("验证码错误，请重新输入！");
        }
        // 验证通过，移除验证码属性
        session.removeAttribute("verify");

        User user = userMapper.selectOne(new QueryWrapper<User>().eq("email", email));
        if(user==null){
            return RespBean.error("该邮箱未注册！");
        }
        user.setPassword(passwordEncoder.encode(password));
        int result = userMapper.updateById(user);
        if(result==1){
            return RespBean.success("密码重置成功！");
        }
        return RespBean.error("密码重置失败！");
    }

    /**
     * 修改密码
     * @return
     */
    @Override
    public RespBean updatePassword(UpdatePwdDto updatePwdDto) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(!passwordEncoder.matches(updatePwdDto.getOldPassword(),user.getPassword()))
        {
            return RespBean.error("密码错误！");
        }else if(passwordEncoder.matches(updatePwdDto.getNewPassword(),user.getPassword())){
            return RespBean.error("新密码与旧密码相同！");
        }
        user.setPassword(passwordEncoder.encode(updatePwdDto.getNewPassword()));
        int result = userMapper.updateById(user);
        if(result==1){
            return RespBean.success("密码修改成功！");
        }
        return RespBean.error("密码修改失败！");
    }

    @Override
    public RespBean uploadImage(MultipartFile file) {

        // 设置文件保存路径
        String profilesPath = "C:/usx_ip/profiles/";
        //System.out.println("程序执行到这里了");
        BufferedOutputStream out = null;
        try {
            // 确保目录存在
            File folder = new File(profilesPath);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            // 获取原始文件名并构造新文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String objectName = UUID.randomUUID().toString() + extension;

            // 创建文件
            File serverFile = new File(folder, objectName);
            out = new BufferedOutputStream(new FileOutputStream(serverFile));

            // 写入文件
            out.write(file.getBytes());
            out.flush();

            // 文件请求路径（调整为实际可访问的路径）
            String fileUrl = "http://localhost:8081/uploadedFiles/" + objectName;
            return RespBean.success("文件上传成功", fileUrl);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件上传失败：{}", e);
            return RespBean.error("文件上传失败");
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
